home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Online / SpeakFreely / src / soundbyte.c < prev    next >
C/C++ Source or Header  |  2000-05-18  |  7KB  |  306 lines

  1. /*
  2.  
  3.     Sound interface for Speak Freely for Unix
  4.  
  5.     Designed and implemented in July of 1990 by John Walker
  6.  
  7. */
  8.  
  9. #include "speakfree.h"
  10. #include <stdio.h>
  11. #include <fcntl.h>
  12. #ifdef AUDIO_DEVICE_FILE
  13.  
  14. #include <errno.h>
  15. #include <sys/ioctl.h>
  16. #define AUDIO_MIN_GAIN 0
  17. #define AUDIO_MAX_GAIN 255
  18.  
  19. static int abuf_size;
  20.  
  21. #ifdef IN_AUDIO_DEV
  22. #define SoundFileIn IN_AUDIO_DEV
  23. #else
  24. #define SoundFileIn     "/dev/audio"
  25. #endif
  26.  
  27. #ifdef OUT_AUDIO_DEV
  28. #define SoundFileOut OUT_AUDIO_DEV
  29. #else
  30. #define SoundFileOut    "/dev/audio"
  31. #endif
  32.  
  33. #ifdef sun
  34. #define AUDIO_CTLDEV    "/dev/audioctl"
  35. #else
  36. #define AUDIO_CTLDEV    "/dev/mixer"
  37. #endif
  38.  
  39. char *devAudioInput = SoundFileIn,    /* Audio device files to open. */
  40.      *devAudioOutput = SoundFileOut,  /* These can overridden by the -y */
  41.      *devAudioControl = AUDIO_CTLDEV; /* option on sfmike and sfspeaker. */
  42.  
  43. #define MAX_GAIN    100
  44.  
  45. struct sound_buf {
  46.     struct sound_buf *snext;          /* Next sound buffer */
  47.     int sblen;                  /* Length of this sound buffer */
  48.     unsigned char sbtext[2];          /* Actual sampled sound */
  49. };
  50.  
  51. /*  Local variables  */
  52. static int paudiof = -1;        /* For playing   */
  53. static int raudiof = -1;        /* For recording */
  54. static int mode    = -1;
  55. static int volume  = 100;
  56.  
  57. static char WriteFile[256];     /* For the template */
  58. static char ReadFile[256];      /* For the template */
  59.  
  60. static short pbuf[BUFL];        /* Buffer for playing */
  61. static short rbuf[BUFL];
  62. static int audiof = -1;           /* Audio device file descriptor */
  63. static int Audio_fd;              /* Audio control port */
  64. #ifdef sun
  65. static audio_info_t Audio_info;       /* Current configuration info */
  66. #endif
  67. struct sound_buf *sbchain = NULL,     /* Sound buffer chain links */
  68.          *sbtail = NULL;
  69. static int sbtotal = 0;           /* Total sample bytes in memory */
  70. static int playing = FALSE;          /* Replay in progress ? */
  71. /* static int playqsize;  */            /* Output queue size */
  72. static int playlen = 0;           /* Length left to play */
  73. static unsigned char *playbuf= NULL;  /* Current play pointer */
  74. static int squelch = 0;           /* Squelch value */
  75. extern int neverRelease = FALSE;     /* Never release audio device.  This
  76.                      is set if we inherited our open
  77.                      audio device file descriptor from
  78.                      a parent process.  If we release
  79.                                          it, there's no way we can get it
  80.                      back, so we glom onto it until
  81.                      we exit. */
  82.  
  83. /* Convert local gain into device parameters */
  84.  
  85. static unsigned scale_gain(g)
  86.   unsigned g;
  87. {
  88.     return (AUDIO_MIN_GAIN + (unsigned)
  89.     ((int) ((((double) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN)) *
  90.     ((double) g / (double) MAX_GAIN)) + 0.5)));
  91. }
  92.  
  93. #ifdef Solaris
  94.  
  95. /*  SETAUBUFSIZE  --  Preset size of internal /dev/audio buffer segments
  96.               Must be called before soundinit()  */
  97.  
  98. static int aubufsize = 2048;          /* Default */
  99.  
  100. void setaubufsize(size)
  101.   int size;
  102. {
  103.     aubufsize = size;
  104. }
  105. #endif
  106.  
  107.  
  108. /*  SOUNDINIT  --  Open the sound peripheral and initialise for
  109.            access.  Return TRUE if successful, FALSE
  110.            otherwise.  */
  111.  int soundinit(iomode)
  112.    int iomode;
  113.  {
  114.    char *variable;
  115.   int punit   = 0;
  116.    int runit   = 0;
  117.  
  118.    /* Save mode for soundplayvol() */
  119.    mode = iomode;
  120.  
  121.    if(iomode == -1) {
  122.      return FALSE;
  123.    }
  124.  
  125.    /* Find out where to read and play audio */
  126.  
  127.    variable = getenv("SPEAKFREE_PLAY_UNIT");
  128.    if(variable) {
  129.      punit = strtol(variable, NULL, 10);
  130.    }
  131.  
  132.    variable = getenv("SPEAKFREE_RECORD_UNIT");
  133.    if(variable) {
  134.      runit = strtol(variable, NULL, 10);
  135.    }
  136.  
  137.    sprintf((char *) WriteFile,
  138.        "AUDIO:BITS/16/FREQUENCY/8000/CHANNELS/1/TYPE/SIGNED/"
  139.        "VOLUME/%d/BUFFER/8192/UNIT/%d", volume, punit);
  140.    sprintf((char *) ReadFile,
  141.        "AUDIO:BITS/16/FREQUENCY/8000/CHANNELS/1/TYPE/SIGNED/"
  142.        "BUFFER/2048/UNIT/%d", runit);
  143.  
  144.    if (iomode != O_RDONLY) {
  145.      if ((paudiof = open(WriteFile, O_WRONLY)) < 0) {
  146.        fprintf(stderr, "Audio open: unable to open \"%s\"\n", WriteFile);
  147.        return FALSE;
  148.      }
  149.    }
  150.  
  151.    if (iomode != O_WRONLY) {
  152.      if ((raudiof = open(ReadFile, O_RDONLY)) < 0) {
  153.        fprintf(stderr, "Audio open: unable to open \"%s\"\n", ReadFile);
  154.        return FALSE;
  155.      }
  156.    }
  157.  
  158.    return TRUE;
  159. }
  160.  
  161. /*  SOUNDTERM  --  Close the sound device.  */
  162.  
  163.  void soundterm()
  164.  {
  165.    if (paudiof >= 0) {
  166.      if (close(paudiof) < 0) {
  167.        perror("closing audio device");
  168.      }
  169.      paudiof = -1;
  170.    }
  171.    if (raudiof >= 0) {
  172.      if (close(raudiof) < 0) {
  173.        perror("closing audio device");
  174.      }
  175.      raudiof = -1;
  176.    }
  177.    mode   = -1;
  178.  }
  179.  
  180.  
  181. /*  SOUND_OPEN_FILE_DESCRIPTORS  --  Obtain file descriptors of open
  182.                      audio and audio control device files.  */
  183.  
  184. void sound_open_file_descriptors(audio_io, audio_ctl)
  185.   int *audio_io, *audio_ctl;
  186. {
  187.     *audio_io = audiof;
  188.     *audio_ctl = Audio_fd;
  189. }
  190.  
  191. /*  SOUNDPLAY  --  Begin playing a sound.  */
  192.  
  193. void soundplay(len, buf)
  194.    int len;
  195.   unsigned char *buf;
  196.  {
  197.    int ios;
  198.    int i;
  199.  
  200.    if(len > BUFL) {
  201.      len = BUFL;
  202.    }
  203.  
  204.    /* Convert µlaw to 16 bit */
  205.    for (i = 0; i < len; i++) {
  206.      pbuf[i] = ulaw2linear(buf[i]);
  207.    }
  208.  
  209.    while (TRUE) {
  210.      ios = write(paudiof, pbuf, len << 1 );
  211.      if (ios == -1) {
  212.        sf_usleep(100000);
  213.     } else {
  214.        ios >>= 1;
  215.        if (ios < len ) {
  216.          buf += ios;
  217.          len -= ios;
  218.       } else {
  219.          break;
  220.        }
  221.      }
  222.    }
  223.  }
  224.  
  225.  
  226. /*  SOUNDPLAYVOL  --  Set playback volume from 0 (silence) to 100 (full on). */
  227.  
  228.  void soundplayvol(value)
  229.    int value;
  230.  {
  231.    volume = value;
  232.    soundterm();
  233.    soundinit(mode);
  234.  }
  235.  
  236.  
  237. /*  SOUNDRECGAIN  --  Set recording gain from 0 (minimum) to 100 (maximum).  */
  238.  
  239.  void soundrecgain(value)
  240.    int value;
  241.  {
  242.  }
  243.  
  244. /*  SOUNDDEST  --  Set destination for generated sound.  If "where"
  245.            is 0, sound goes to the built-in speaker; if
  246.            1, to the audio output jack. */
  247.  
  248.  
  249.  void sounddest(where)
  250.    int where;
  251.  {
  252.  }
  253.  
  254. /*  SOUNDGRAB  --  Return audio information in the record queue.  */
  255.  
  256. int soundgrab(buf, len)
  257.      char *buf;
  258.      int len;
  259.  {
  260.    long read_size;
  261.    int c;
  262.    int i;
  263.  
  264.    if(len > BUFL) {
  265.      len = BUFL;
  266.    }
  267.  
  268.    read_size = len;
  269.  
  270.    while (TRUE) {
  271.      c = read(raudiof, rbuf, read_size << 1);
  272.      if (c < 0) {
  273.        if (errno == EINTR) {
  274.          continue;
  275.        }
  276.      } else {
  277.        c >>= 1;
  278.      }
  279.      break;
  280.    }
  281.    if (c < 0) {
  282.      perror("soundgrab");
  283.    }
  284.  
  285.    /* Convert 16 bit to µlaw */
  286.    for (i = 0; i < len; i++) {
  287.      buf[i] = linear2ulaw(rbuf[i]);
  288.    }
  289.  
  290.    return c;
  291.  }
  292.  
  293.  
  294. /*  SOUNDFLUSH    --  Flush any queued sound.  */
  295.  
  296.  void soundflush()
  297.  {
  298.  /*
  299.    soundterm();
  300.    soundinit(mode);
  301.  */
  302.  }
  303.  
  304.  
  305. #endif /* AUDIO_DEVICE_FILE */
  306.